namespace SharpGym.WinRT.Model
{
    using System;

    public class AvaliacaoFisica : BaseModel
    {
        private const double epsilon = 0.0001;
        private double _abdominalDC;
        private double _abdominalP;
        private Aluno _aluno;
        private double _anteBracoP;
        private double _bicepsDC;
        private double _bracoContraidoP;
        private double _bracoP;
        private double _coxaP;
        private DateTime _data;
        private double _escapularDC;
        private double _estatura;
        private int _numero;
        private double _panturrilhaDC;
        private double _peitoralDC;
        private double _pelveP;
        private double _pernaP;
        private double _peso;
        private double _punhoL;
        private double _quadricepsDC;
        private double _supraIliacaDC;
        private double _toraxicaDC;
        private double _tricepsDC;
        private double _umeroL;

        public int Numero
        {
            get { return _numero; }
            set
            {
                if (Numero == value)
                    return;

                _numero = value;
                OnPropertyChanged("Numero");
            }
        }

        public DateTime Data
        {
            get { return _data; }
            set
            {
                if (Data == value)
                    return;

                _data = value;
                OnPropertyChanged("Data");
            }
        }

        public double Peso
        {
            get { return _peso; }
            set
            {
                if (Math.Abs(Peso - value) < epsilon)
                    return;

                _peso = value;
                OnPropertyChanged("Peso");
            }
        }

        public double Estatura
        {
            get { return _estatura; }
            set
            {
                if (Math.Abs(Estatura - value) < epsilon)
                    return;

                _estatura = value;
                OnPropertyChanged("Estatura");
            }
        }

        public double TricepsDC
        {
            get { return _tricepsDC; }
            set
            {
                if (Math.Abs(TricepsDC - value) < epsilon)
                    return;

                _tricepsDC = value;
                OnPropertyChanged("TricepsDC");
            }
        }

        public double EscapularDC
        {
            get { return _escapularDC; }
            set
            {
                if (Math.Abs(EscapularDC - value) < epsilon)
                    return;

                _escapularDC = value;
                OnPropertyChanged("EscapularDC");
            }
        }

        public double PeitoralDC
        {
            get { return _peitoralDC; }
            set
            {
                if (Math.Abs(PeitoralDC - value) < epsilon)
                    return;

                _peitoralDC = value;
                OnPropertyChanged("PeitoralDC");
            }
        }

        public double ToraxicaDC
        {
            get { return _toraxicaDC; }
            set
            {
                if (Math.Abs(ToraxicaDC - value) < epsilon)
                    return;

                _toraxicaDC = value;
                OnPropertyChanged("ToraxicaDC");
            }
        }

        public double SupraIliacaDC
        {
            get { return _supraIliacaDC; }
            set
            {
                if (Math.Abs(SupraIliacaDC - value) < epsilon)
                    return;

                _supraIliacaDC = value;
                OnPropertyChanged("SupraIliacaDC");
            }
        }

        public double AbdominalDC
        {
            get { return _abdominalDC; }
            set
            {
                if (Math.Abs(AbdominalDC - value) < epsilon)
                    return;

                _abdominalDC = value;
                OnPropertyChanged("AbdominalDC");
            }
        }

        public double QuadricepsDC
        {
            get { return _quadricepsDC; }
            set
            {
                if (Math.Abs(QuadricepsDC - value) < epsilon)
                    return;

                _quadricepsDC = value;
                OnPropertyChanged("QuadricepsDC");
            }
        }

        public double PanturrilhaDC
        {
            get { return _panturrilhaDC; }
            set
            {
                if (Math.Abs(PanturrilhaDC - value) < epsilon)
                    return;

                _panturrilhaDC = value;
                OnPropertyChanged("PanturrilhaDC");
            }
        }

        public double BicepsDC
        {
            get { return _bicepsDC; }
            set
            {
                if (Math.Abs(BicepsDC - value) < epsilon)
                    return;

                _bicepsDC = value;
                OnPropertyChanged("BicepsDC");
            }
        }

        public double PernaP
        {
            get { return _pernaP; }
            set
            {
                if (Math.Abs(PernaP - value) < epsilon)
                    return;

                _pernaP = value;
                OnPropertyChanged("PernaP");
            }
        }

        public double CoxaP
        {
            get { return _coxaP; }
            set
            {
                if (Math.Abs(CoxaP - value) < epsilon)
                    return;

                _coxaP = value;
                OnPropertyChanged("CoxaP");
            }
        }

        public double PelveP
        {
            get { return _pelveP; }
            set
            {
                if (Math.Abs(PelveP - value) < epsilon)
                    return;

                _pelveP = value;
                OnPropertyChanged("PelveP");
            }
        }

        public double AbdominalP
        {
            get { return _abdominalP; }
            set
            {
                if (Math.Abs(AbdominalP - value) < epsilon)
                    return;

                _abdominalP = value;
                OnPropertyChanged("AbdominalP");
            }
        }

        public double AnteBracoP
        {
            get { return _anteBracoP; }
            set
            {
                if (Math.Abs(AnteBracoP - value) < epsilon)
                    return;

                _anteBracoP = value;
                OnPropertyChanged("AnteBracoP");
            }
        }

        public double BracoP
        {
            get { return _bracoP; }
            set
            {
                if (Math.Abs(BracoP - value) < epsilon)
                    return;

                _bracoP = value;
                OnPropertyChanged("BracoP");
            }
        }

        public double BracoContraidoP
        {
            get { return _bracoContraidoP; }
            set
            {
                if (Math.Abs(BracoContraidoP - value) < epsilon)
                    return;

                _bracoContraidoP = value;
                OnPropertyChanged("BracoContraidoP");
            }
        }

        public double PunhoL
        {
            get { return _punhoL; }
            set
            {
                if (Math.Abs(PunhoL - value) < epsilon)
                    return;

                _punhoL = value;
                OnPropertyChanged("PunhoL");
            }
        }

        public double UmeroL
        {
            get { return _umeroL; }
            set
            {
                if (Math.Abs(UmeroL - value) < epsilon)
                    return;

                _umeroL = value;
                OnPropertyChanged("UmeroL");
            }
        }

        public double IMC
        {
            get { return Peso/(Estatura*Estatura); }
        }

        public double RCQ
        {
            get { return AbdominalP/PelveP; }
        }

        public double PorcentagemGordura
        {
            get { return (TricepsDC + EscapularDC + SupraIliacaDC + AbdominalDC)*0.153 + 5.783; }
        }

        public double PorcentagemLivreGordura
        {
            get { return 100 - PorcentagemGordura; }
        }

        public double PesoGordura
        {
            get { return Peso*PorcentagemGordura/100; }
        }

        public double PesoMagro
        {
            get { return Peso*PorcentagemLivreGordura/100; }
        }

        public Aluno Aluno
        {
            get { return _aluno; }
            set
            {
                _aluno = value;
                OnPropertyChanged("Aluno");
            }
        }

        public double PorcentagemIdealGordura(DateTime Nascimento)
        {
            return 12 + (((DateTime.Today - Nascimento).TotalDays/365) - 30)*0.2;
        }

        public double PorcentagemGorduraSobra(DateTime Nascimento)
        {
            return PorcentagemGordura - PorcentagemIdealGordura(Nascimento);
        }

        public double PesoIdeal(DateTime Nascimento)
        {
            return (Peso*(PorcentagemLivreGordura/100))/(1 - (PorcentagemIdealGordura(Nascimento)/100));
        }
    }
}